// Kokomi.js - Three.js 组件框架
import * as kokomi from "kokomi.js";
// Three.js - 3D 渲染引擎
import * as THREE from "three";
// GSAP - 动画库
import gsap from "gsap";

import type Experience from "../Experience";

/**
 * 雷达动画组件
 * 使用车身轮廓等高线向外扩散的雷达扫描效果
 */
export default class RadarAnimation extends kokomi.Component {
  declare base: Experience;
  container: THREE.Group; // 容器组
  carOutlines: THREE.Group; // 车身轮廓组
  otherVehicles: THREE.Group; // 其他车辆组
  roadLines: THREE.Group; // 道路标线组
  isAnimating: boolean = false; // 是否正在动画
  animationSpeed: number = 0; // 动画速度
  outlineWaves: Array<{
    group: THREE.Group;
    scale: number;
    opacity: number;
    targetScale: number;
  }> = []; // 轮廓波浪数组
  intervalId: NodeJS.Timeout | null = null; // 定时器ID
  carContourPoints: THREE.Vector2[] = []; // 车身轮廓点
  vehicleData: Array<{
    mesh: THREE.Mesh;
    lane: number;
    speed: number;
  }> = [];

  constructor(base: Experience) {
    super(base);

    // 创建容器组
    this.container = new THREE.Group();
    this.container.visible = false; // 初始隐藏
    this.container.position.y = 0.02; // 略高于地面，避免 z-fighting

    // 创建车身轮廓组
    this.carOutlines = new THREE.Group();
    this.container.add(this.carOutlines);

    // 创建其他车辆组
    this.otherVehicles = new THREE.Group();
    this.container.add(this.otherVehicles);

    // 创建道路标线组
    this.roadLines = new THREE.Group();
    this.container.add(this.roadLines);

    // 获取车身轮廓点
    this.extractCarContour();

    // 创建道路标线
    this.createRoadLines();

    // 创建其他车辆
    this.createOtherVehicles();
  }

  /**
   * 提取车身轮廓点（保留备用）
   */
  extractCarContour() {
    // 暂时不使用车身轮廓，改用同心圆
    this.carContourPoints = [];
  }

  /**
   * 创建虚线圆环（使用点组成）
   */
  createDashedCircle(radius: number, segments: number = 80, dashCount: number = 60): THREE.Points {
    const points: THREE.Vector3[] = [];
    const dashLength = (Math.PI * 2) / dashCount;
    const gapRatio = 0.4; // 间隙比例
    
    for (let i = 0; i < dashCount; i++) {
      const startAngle = i * dashLength;
      const endAngle = startAngle + dashLength * (1 - gapRatio);
      
      // 每个虚线段用3-5个点组成
      const pointsPerDash = 4;
      for (let j = 0; j <= pointsPerDash; j++) {
        const angle = startAngle + (endAngle - startAngle) * (j / pointsPerDash);
        const x = Math.cos(angle) * radius;
        const z = Math.sin(angle) * radius;
        points.push(new THREE.Vector3(x, 0, z));
      }
    }
    
    const geometry = new THREE.BufferGeometry().setFromPoints(points);
    const material = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 0.25, // 增加点的大小，让线条更粗
      transparent: true,
      opacity: 0.8,
      sizeAttenuation: true,
    });
    
    return new THREE.Points(geometry, material);
  }

  /**
   * 创建一组同心圆环（3条）
   */
  createOutlineWave() {
    const waveGroup = new THREE.Group();
    const numRings = 4; // 三圈同心圆
    const baseRadius = 2.0; // 起始半径
    
    for (let i = 0; i < numRings; i++) {
      const radius = baseRadius + i * 0.8; // 每圈间隔0.8单位
      const opacity = 1 - i * 0.25; // 逐渐变淡
      
      // 创建虚线圆环
      const circle = this.createDashedCircle(radius, 80, 60);
      const material = circle.material as THREE.PointsMaterial;
      material.opacity = opacity * 0.9;
      material.color.set(0xffffff); // 白色点
      
      waveGroup.add(circle);
    }
    
    return waveGroup;
  }

  /**
   * 发射一波圆环扩散
   */
  emitWave() {
    const waveGroup = this.createOutlineWave();
    waveGroup.scale.set(1, 1, 1);
    this.carOutlines.add(waveGroup);
    
    // 添加到动画队列
    const waveData = {
      group: waveGroup,
      scale: 1,
      opacity: 1,
      targetScale: 4.5, // 扩散到4.5倍大小
    };
    this.outlineWaves.push(waveData);
    
    // 动画：向外扩散并淡出
    gsap.to(waveData, {
      scale: waveData.targetScale,
      opacity: 0,
      duration: 2.5,
      ease: "power2.out",
      onUpdate: () => {
        waveGroup.scale.set(waveData.scale, waveData.scale, waveData.scale);
        // 更新所有圆环的透明度
        waveGroup.children.forEach((child, index) => {
          if (child instanceof THREE.Points) {
            const material = child.material as THREE.PointsMaterial;
            material.opacity = waveData.opacity * (1 - index * 0.25);
          }
        });
      },
      onComplete: () => {
        // 动画完成后移除
        this.carOutlines.remove(waveGroup);
        waveGroup.traverse((child) => {
          if (child instanceof THREE.Points) {
            child.geometry.dispose();
            (child.material as THREE.Material).dispose();
          }
        });
        const index = this.outlineWaves.indexOf(waveData);
        if (index > -1) {
          this.outlineWaves.splice(index, 1);
        }
      },
    });
  }

  /**
   * 创建道路标线
   */
  createRoadLines() {
    const lineCount = 25;
    const lineLength = 1.0;
    const lineWidth = 0.08;
    const spacing = 1.8;
    const laneWidth = 1.8;

    for (let lane = -2; lane <= 2; lane++) {
      if (lane === 0) continue;

      for (let i = 0; i < lineCount; i++) {
        const geometry = new THREE.PlaneGeometry(lineWidth, lineLength);
        const material = new THREE.MeshBasicMaterial({
          color: 0xffffff,
          transparent: true,
          opacity: 0.4,
          side: THREE.DoubleSide,
        });
        const line = new THREE.Mesh(geometry, material);

        line.position.x = lane * laneWidth;
        line.position.z = i * spacing - lineCount * spacing / 2;
        line.rotation.x = -Math.PI / 2;

        this.roadLines.add(line);
      }
    }
  }


  /**
   * 创建其他车辆
   */
  createOtherVehicles() {
    const vehicleCount = 4;
    const laneWidth = 1.8;
    const lanes = [-2, -1, 1, 2];

    for (let i = 0; i < vehicleCount; i++) {
      const lane = lanes[Math.floor(Math.random() * lanes.length)];

      const geometry = new THREE.BoxGeometry(0.9, 0.4, 1.8);
      const material = new THREE.MeshStandardMaterial({
        color: 0x888888,
        metalness: 0.3,
        roughness: 0.7,
      });
      const vehicle = new THREE.Mesh(geometry, material);

      vehicle.position.x = lane * laneWidth;
      vehicle.position.y = 0.2;
      vehicle.position.z = Math.random() * 20 - 10;

      this.otherVehicles.add(vehicle);

      this.vehicleData.push({
        mesh: vehicle,
        lane,
        speed: 0.6 + Math.random() * 0.4,
      });
    }
  }

  /**
   * 每帧更新
   */
  update() {
    if (!this.isAnimating) return;

    // 更新道路标线位置（向下移动）
    this.roadLines.children.forEach((line) => {
      line.position.z += this.animationSpeed;
      if (line.position.z > 22) {
        line.position.z = -22;
      }
    });

    // 更新其他车辆位置
    this.vehicleData.forEach((data) => {
      data.mesh.position.z += this.animationSpeed * data.speed;
      if (data.mesh.position.z > 15) {
        data.mesh.position.z = -15;
      }
    });
  }

  /**
   * 开始动画
   */
  start() {
    this.isAnimating = true;
    this.container.visible = true;

    // 平滑增加速度
    gsap.to(this, {
      animationSpeed: 0.1,
      duration: 1,
      ease: "power2.out",
    });

    // 立即发射第一波
    this.emitWave();

    // 每隔1秒发射一波轮廓扩散
    this.intervalId = setInterval(() => {
      if (this.isAnimating) {
        this.emitWave();
      }
    }, 1000);
  }

  /**
   * 停止动画
   */
  stop() {
    // 清除定时器
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }

    // 平滑减少速度
    gsap.to(this, {
      animationSpeed: 0,
      duration: 0.8,
      ease: "power2.in",
      onComplete: () => {
        this.isAnimating = false;
        
        // 清除所有圆环波浪
        this.outlineWaves.forEach((wave) => {
          gsap.killTweensOf(wave);
          this.carOutlines.remove(wave.group);
          wave.group.traverse((child) => {
            if (child instanceof THREE.Points) {
              child.geometry.dispose();
              (child.material as THREE.Material).dispose();
            }
          });
        });
        this.outlineWaves = [];
        
        this.container.visible = false;
      },
    });
  }

  /**
   * 添加到场景
   */
  addExisting() {
    this.base.scene.add(this.container);
  }

  /**
   * 销毁组件
   */
  destroy() {
    this.stop();
    
    // 清除定时器
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
    
    // 清理所有资源
    this.container.traverse((child) => {
      if (child instanceof THREE.Mesh || child instanceof THREE.Points || child instanceof THREE.Line) {
        child.geometry.dispose();
        if (Array.isArray(child.material)) {
          child.material.forEach((mat) => mat.dispose());
        } else {
          child.material.dispose();
        }
      }
    });
    
    this.base.scene.remove(this.container);
  }
}
